home *** CD-ROM | disk | FTP | other *** search
- Submitted-by: berg@pool.informatik.rwth-aachen.de (Stephen R. van den Berg)
-
- It seems that POSIX 1003.1 describes the semantics for setgid() in
- such a way that they *needlessly* cripple certain applications.
-
- As I understand it, POSIX 1003.1 specifies a very useful construction
- called "saved user and group ids".
-
- The saved ids principally get set whenever a process performs an execve()
- call. This first causes the effective ids to be set according to the settings
- on the binary being executed, and shortly thereafter, the saved ids are
- copied over from the effective ids.
-
- This allows graceful switching between the real ids and the saved ids,
- because both the real and saved ids will not be affected by subsequent
- setuid() and setgid() calls, only the effective ids are changed.
-
- So far, so good. Then I notice a small problem on the horizon. When the
- program performs a setgid() while the effective uid of the process is zero,
- this not only affects the real and effective gid, but it ALSO affects the
- saved gid.
-
- Now I can't imagine any program making use of or depending on this
- (mis)feature.
-
- Sure, I heard the classical argument, programs like "login" and "su" need
- to be able to set the saved gid of a process to prevent security holes.
- But that is not true. They do not need to set it at all. It would be
- more than sufficient if both su and login could only set their real
- and effective gids. When they then subsequently execve() the following
- shell (or other program), the saved gid will *automatically* be copied
- from the effective gid.
-
- Why do I care, you might wonder. Well, consider the following:
-
- -rwsr-sr-x 1 root mail 49152 Mar 12 18:19 /local/bin/procmail
- drwxrwxr-x 2 root mail 1024 Mar 12 18:24 /usr/mail
-
- If procmail is called by user A who is in group B, it then has to
- assume the identity of a completely other user (the recipient) in order
- to deliver the mail.
-
- Say the recipient is user C in group D.
-
- Then the following SHOULD happen to the ids while it is executing:
- (- means no change)
-
- Previous event: uid euid suid gid egid sgid
-
- Start procmail A root root B mail mail
- initgroups() for user C - - - - - -
- setgid(D) - - - D D mail
- setuid(C) C C C - - -
- access some files for user D
- start programs for user D
- setgid(mail) - - - - mail -
- create a file in /usr/mail
- setgid(D) - - - - D -
- access some files for user D
- start programs for user D
- exit
-
-
- Now, POSIX says that the saved gid changes to D as well when the first
- setgid(D) is executed (because the euid is zero). This makes it *impossible*
- to somehow flip back the gid to "mail", like I try to do in the second
- setgid() call.
-
- But, I can't delay this setgid(D) call till after the setuid() call because
- then I may no longer have permissions to join group D.
-
- This raises these questions:
- - Why did POSIX specify it the way it did? Any compelling reason?
- - Is there any (fictitious) program that depends on the semantics of
- setgid() being so that it affects the saved gid when being root?
- - Is there any way to accomplish this flipping between two groups
- that I overlooked?
- - If not, can we do anything about the standard (to fix this, I can
- not imagine even one program breaking if we do)?
- - What about this rumoured setrgid() or setregid() call? Would that
- exhibit the correct behaviour? Or does it exhibit these
- braindamaged semantics (affecting the saved gid when root) as well?
-
- Any comments/answers/hints appreciated.
-
- --
- Sincerely, berg@pool.informatik.rwth-aachen.de
- Stephen R. van den Berg (AKA BuGless). berg@physik.tu-muenchen.de
-
- I've never been superstitious! Knock on wood.
-
-
- Volume-Number: Volume 31, Number 82
-
-